package com.iecas.launch;

import com.iecas.context.ClientContext;
import com.iecas.context.GlobalContext;
import com.iecas.entity.Bullet;
import com.iecas.entity.Explosion;
import com.iecas.entity.Tank;
import com.iecas.entity.Wall;
import com.iecas.enums.BizEnum;
import com.iecas.enums.Direction;
import com.iecas.holder.TokenHolder;
import com.iecas.request.FireReq;
import com.iecas.request.MoveReq;
import com.iecas.runnner.HeartBeatRunner;
import com.iecas.utils.RequestUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Random;

public class GameFrame extends JFrame {
    public static final int WIDTH = 1280 / 2;
    public static final int HEIGHT = 960 / 2;
    Client client;
    HeartBeatRunner heartBeatRunner;

    public GameFrame() {
        initUI();
        heartBeatRunner = new HeartBeatRunner();
    }

    private void initUI() {
        add(new GamePanel());
        setTitle("TANK");
        setSize(WIDTH, HEIGHT);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public void startSendHeartBeat() {
        heartBeatRunner.setClient(client);
        heartBeatRunner.start();
    }

    public void stopSendHeartBeat() {
        heartBeatRunner.shutdown();
    }


    public void setClient(Client client) {
        this.client = client;
    }


    // 游戏面板类
    class GamePanel extends JPanel implements ActionListener, KeyListener {
        private static final int DELAY = 15;

//        private PlayerTank player;
//        private java.util.List<EnemyTank> enemies;
//        private java.util.List<com.iecas.test.Bullet> bullets;
//        private java.util.List<Explosion> explosions;
//        private java.util.List<Wall> walls;

        private Timer timer;
        private boolean[] keys;
        private int score;
        private int lives;
        private boolean gameOver;
//        Tank tank = new Tank();
//        ArrayList<Bullet> bullets = new ArrayList<Bullet>();

        public GamePanel() {
            initGame();
        }


        private void initGame() {
            setBackground(Color.BLACK);
            setPreferredSize(new Dimension(GameFrame.WIDTH, GameFrame.HEIGHT));
            setFocusable(true);

            keys = new boolean[KeyEvent.KEY_LAST + 1];
            addKeyListener(this);

//            player = new PlayerTank(375, 500);
//            enemies = new ArrayList<>();
//            bullets = new ArrayList<>();
//            explosions = new ArrayList<>();
//            walls = new ArrayList<>();

            score = 0;
            lives = 3;
            gameOver = false;

            createWalls();
            createEnemies();

            timer = new Timer(DELAY, this);
            timer.start();


        }

        private void createWalls() {
            // 创建障碍物
//            for (int i = 0; i < 10; i++) {
//                for (int j = 0; j < 3; j++) {
//                    walls.add(new Wall(100 + i * 60, 200 + j * 30));
//                }
//            }
        }

        private void createEnemies() {
            Random rand = new Random();
//            for (int i = 0; i < 5; i++) {
//                enemies.add(new EnemyTank(100 + i * 150, 50, rand.nextInt(4)));
//            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            ClientContext clientContext = GlobalContext.getClientContext();

            drawPlayer(g, clientContext.getTankMap());
//            drawEnemies(g);
            drawBullets(g, clientContext.getBulletList());
            drawWalls(g, clientContext.getWalls());
            drawExplosions(g, clientContext.getExplosions());
//            drawInfo(g);
        }

        private void drawPlayer(Graphics g, Map<String, Tank> tankMap) {
//            System.out.println(tankMap);
            for (String tankId : tankMap.keySet()) {
                Tank tank = tankMap.get(tankId);
                g.setColor(Color.GREEN);
                g.fillRect(tank.getX(), tank.getY(), 30, 30);

                // 绘制炮管
                g.setColor(Color.DARK_GRAY);
                switch (tank.getDirection()) {
                    case UP: // 上
                        g.fillRect(tank.getX() + 12, tank.getY() - 10, 6, 15);
                        break;
                    case RIGHT: // 右
                        g.fillRect(tank.getX() + tank.getWidth() - 3, tank.getY() + 12, 15, 6);
                        break;
                    case DOWN: // 下
                        g.fillRect(tank.getX() + 12, tank.getY() + tank.getHeight() - 3, 6, 15);
                        break;
                    case LEFT: // 左
                        g.fillRect(tank.getX() - 10, tank.getY() + 12, 15, 6);
                        break;
                }
                drawInfo(g, tank);
            }
        }

        private void drawEnemies(Graphics g) {
//            for (EnemyTank enemy : enemies) {
//                if (enemy.isAlive()) {
//                    g.setColor(Color.RED);
//                    g.fillRect(enemy.getX(), enemy.getY(), 30, 30);
//
//                    // 绘制炮管
//                    g.setColor(Color.DARK_GRAY);
//                    switch (enemy.getDirection()) {
//                        case 0: // 上
//                            g.fillRect(enemy.getX() + 12, enemy.getY() - 10, 6, 15);
//                            break;
//                        case 1: // 右
//                            g.fillRect(enemy.getX() + 15, enemy.getY() + 12, 15, 6);
//                            break;
//                        case 2: // 下
//                            g.fillRect(enemy.getX() + 12, enemy.getY() + 15, 6, 15);
//                            break;
//                        case 3: // 左
//                            g.fillRect(enemy.getX() - 10, enemy.getY() + 12, 15, 6);
//                            break;
//                    }
//                }
//            }
        }

        private void drawBullets(Graphics g, java.util.List<Bullet> bulletList) {
            g.setColor(Color.YELLOW);
            for (Bullet bullet : bulletList) {
                g.fillOval(bullet.getX(), bullet.getY(), bullet.getWidth(), bullet.getHeight());
            }
        }

        private void drawWalls(Graphics g, java.util.List<Wall> walls) {
            g.setColor(Color.GRAY);
            for (Wall wall : walls) {
                g.fillRect(wall.getX(), wall.getY(), wall.getWidth(), wall.getHeight());
            }
        }

        private void drawExplosions(Graphics g, java.util.List<Explosion> explosions) {
            for (Explosion explosion : explosions) {
                g.setColor(Color.ORANGE);
                g.fillOval(explosion.getX(), explosion.getY(), explosion.getSize(), explosion.getSize());
            }
        }

        private void drawInfo(Graphics g, Tank tank) {
            g.setColor(Color.WHITE);
            g.setFont(new Font("Arial", Font.BOLD, 12));
            g.drawString(tank.getUsername() + "(" + tank.getX() + "," + tank.getY() + ")", tank.getX() - 16, tank.getY() - 16);

//            if (gameOver) {
//                g.setFont(new Font("Arial", Font.BOLD, 36));
//                g.drawString("游戏结束!", GameFrame.WIDTH / 2 - 80, GameFrame.HEIGHT / 2);
//                g.setFont(new Font("Arial", Font.BOLD, 16));
//                g.drawString("按R键重新开始", GameFrame.WIDTH / 2 - 50, GameFrame.HEIGHT / 2 + 40);
//            }
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            update();
            repaint();
        }

        private void update() {
//            if (gameOver) {
//                if (keys[KeyEvent.VK_R]) {
//                    initGame();
//                }
//                return;
//            }
            updatePlayer();
            // 更新玩家坦克
//            if (player.isAlive()) {
//                updatePlayer();
//            } else {
//                lives--;
//                if (lives > 0) {
//                    player.respawn(375, 500);
//                } else {
//                    gameOver = true;
//                }
//            }
//
//            // 更新敌人坦克
//            updateEnemies();
//
//            // 更新子弹
//            updateBullets();
//
//            // 更新爆炸效果
//            updateExplosions();
//
//            // 检查游戏是否胜利
//            if (enemies.isEmpty()) {
//                createEnemies();
//            }
        }

        private void updatePlayer() {
            boolean isMove = false;
            boolean isFire = false;
            Direction newDirection = null;
            if (keys[KeyEvent.VK_UP]) {
                newDirection = Direction.UP;
                isMove = true;
            } else if (keys[KeyEvent.VK_RIGHT]) {
                newDirection = Direction.RIGHT;
                isMove = true;
            } else if (keys[KeyEvent.VK_DOWN]) {
                newDirection = Direction.DOWN;
                isMove = true;
            } else if (keys[KeyEvent.VK_LEFT]) {
                newDirection = Direction.LEFT;
                isMove = true;
            } else if (keys[KeyEvent.VK_SPACE]) {
                isFire = true;
            }
            if (isMove) {
                MoveReq moveReq = new MoveReq();
                moveReq.setCode(BizEnum.MOVE_REQ.getCode());
                moveReq.setToken(TokenHolder.get());
                moveReq.setDirection(newDirection);
//                moveReq.setKeys(keys);
                ByteBuffer encode = RequestUtils.encode(moveReq);
                client.write(encode);
            }
//            // 发射子弹
            if (isFire) {
                FireReq fireReq = new FireReq();
                fireReq.setCode(BizEnum.FIRE_REQ.getCode());
                fireReq.setToken(TokenHolder.get());
                ByteBuffer encode = RequestUtils.encode(fireReq);
                client.write(encode);
            }
        }

        private void updateEnemies() {
//            Random rand = new Random();
//
//            for (EnemyTank enemy : enemies) {
//                if (enemy.isAlive()) {
//                    // 随机改变方向
//                    if (rand.nextInt(100) < 2) {
//                        enemy.setDirection(rand.nextInt(4));
//                    }
//
//                    // 移动
//                    int dx = 0;
//                    int dy = 0;
//
//                    switch (enemy.getDirection()) {
//                        case 0: dy = -2; break;
//                        case 1: dx = 2; break;
//                        case 2: dy = 2; break;
//                        case 3: dx = -2; break;
//                    }
//
//                    // 检查移动是否会导致碰撞
//                    if (!checkCollision(enemy.getX() + dx, enemy.getY(), enemy.getDirection())) {
//                        enemy.setX(enemy.getX() + dx);
//                    }
//
//                    if (!checkCollision(enemy.getX(), enemy.getY() + dy, enemy.getDirection())) {
//                        enemy.setY(enemy.getY() + dy);
//                    }
//
//                    // 边界检查
//                    enemy.setX(Math.max(0, Math.min(enemy.getX(), TankWarGam1e.WIDTH - 30)));
//                    enemy.setY(Math.max(0, Math.min(enemy.getY(), TankWarGam1e.HEIGHT - 30)));
//
//                    // 发射子弹
//                    if (rand.nextInt(100) < 3 && enemy.canFire()) {
//                        bullets.add(enemy.fire());
//                    }
//                }
//            }
        }

        private void updateBullets() {
//            java.util.List<com.iecas.test.Bullet> bulletsToRemove = new ArrayList<>();
//
//            for (com.iecas.test.Bullet bullet : bullets) {
//                bullet.move();
//
//                // 检查子弹是否超出边界
//                if (bullet.getX() < 0 || bullet.getX() > TankWarGam1e.WIDTH ||
//                        bullet.getY() < 0 || bullet.getY() > TankWarGam1e.HEIGHT) {
//                    bulletsToRemove.add(bullet);
//                    continue;
//                }
//
//                // 检查子弹是否击中墙壁
//                boolean hitWall = false;
//                for (Wall wall : walls) {
//                    if (bullet.intersects(wall)) {
//                        bulletsToRemove.add(bullet);
//                        hitWall = true;
//                        break;
//                    }
//                }
//
//                if (hitWall) continue;
//
//                // 检查玩家子弹是否击中敌人
//                if (bullet.isPlayerBullet()) {
//                    for (EnemyTank enemy : enemies) {
//                        if (enemy.isAlive() && bullet.intersects(enemy)) {
//                            bulletsToRemove.add(bullet);
//                            enemy.setAlive(false);
//                            explosions.add(new Explosion(enemy.getX(), enemy.getY()));
//                            score += 100;
//                            break;
//                        }
//                    }
//                }
//                // 检查敌人子弹是否击中玩家
//                else {
//                    if (player.isAlive() && bullet.intersects(player)) {
//                        bulletsToRemove.add(bullet);
//                        player.setAlive(false);
//                        explosions.add(new Explosion(player.getX(), player.getY()));
//                        break;
//                    }
//                }
//            }
//
//            // 移除需要删除的子弹
//            bullets.removeAll(bulletsToRemove);
//
//            // 移除死亡的敌人
//            enemies.removeIf(enemy -> !enemy.isAlive());
        }

        private void updateExplosions() {
//            java.util.List<Explosion> explosionsToRemove = new ArrayList<>();
//
//            for (Explosion explosion : explosions) {
//                explosion.update();
//                if (explosion.isFinished()) {
//                    explosionsToRemove.add(explosion);
//                }
//            }
//
//            explosions.removeAll(explosionsToRemove);
        }

        private boolean checkCollision(int x, int y, Direction direction) {
//            Rectangle tankRect = new Rectangle(x, y, 30, 30);
//
//            // 检查与墙壁的碰撞
//            for (Wall wall : walls) {
//                if (tankRect.intersects(wall.getBounds())) {
//                    return true;
//                }
//            }
//
//            // 检查与敌人的碰撞（仅玩家需要检查）
//            if (direction == player.getDirection() && x == player.getX() && y == player.getY()) {
//                for (EnemyTank enemy : enemies) {
//                    if (enemy.isAlive() && tankRect.intersects(enemy.getBounds())) {
//                        return true;
//                    }
//                }
//            }
//
            return false;
        }

        @Override
        public void keyPressed(KeyEvent e) {
            int keyCode = e.getKeyCode();
            keys[keyCode] = true;
        }

        @Override
        public void keyReleased(KeyEvent e) {
            int keyCode = e.getKeyCode();
            keys[keyCode] = false;
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }
    }

}
